<template>
  <div class="editor">
    <div id="toolbar" slot="toolbar">
      <span class="ql-formats">
        <button type="button" class="ql-image">插入图片</button>
      </span>
    </div>
    <div ref="editor" class="editor-content" />
    <div class="calc">{{ length }}/{{ maxLength }}</div>
    <input
      id="uploadImg"
      type="file"
      style="display: none"
      accept="image/png, image/jpeg, image/gif"
      @change="uploadImage"
    />
  </div>
</template>

<script>
import Quill from "quill";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import httpApi from "@/api/common";

export default {
  props: {
    content: {
      type: String
    },
    maxLength: {
      type: Number,
      default: 300
    },
    placeholder: {
      type: String,
      required: false,
      default: ""
    }
  },
  data() {
    return {
      length: 0,
      MAXLENGTH: this.maxLength,
      editor: null
    };
  },
  mounted() {
    this.initEditor();
  },
  beforeDestroy() {
    this.editor = null;
  },
  watch: {
    content: {
      immediate: true,
      handler(v) {
        this.$nextTick(() => {
          if (v && this.editor) {
            this.editor.container.firstChild.innerHTML = v;
          }
        });
      }
    }
  },
  methods: {
    initEditor() {
      let placeholder = "";
      if (this.placeholder) {
        placeholder = `${this.placeholder}，最多${this.maxLength}字符`;
      } else {
        placeholder = `请输入内容，最多${this.maxLength}字符`;
      }

      this.editor = new Quill(this.$refs.editor, {
        placeholder: placeholder,
        modules: {
          toolbar: "#toolbar"
        },
        theme: "snow"
      });

      this.editor
        .getModule("toolbar")
        .addHandler("image", this.uploadImageHandler);

      this.editor.on("text-change", (delta) => {
        this.length = this.editor.getLength() - 1;
        if (this.length > this.MAXLENGTH) {
          let d = delta[1];
          if (d && d.insert) {
            this.delta.deleteText(this.MAXLENGTH, d.insert.length);
          } else {
            this.editor.deleteText(this.MAXLENGTH, 1000);
          }
        } else {
          this.$emit("change", this.length);
        }
      });
    },
    uploadImageHandler() {
      const input = document.querySelector("#uploadImg");
      input.value = "";
      input.click();
    },
    async uploadImage(event) {
      const formData = new FormData();
      formData.append("file", event.target.files[0]);
      httpApi.uploadFile(formData).then((res) => {
        if (res.retcode === 0) {
          let range = this.editor.getSelection();
          this.insertEmbed(range.index, "image", res.data.url);
          this.editor.setSelection(range.index + 1);
        } else {
          this.message.error("上传失败");
        }
      });
    },
    insertEmbed(index, type, value) {
      if (this.editor) {
        this.editor.insertEmbed(index, type, value);
        let divQlEditor = document.getElementsByClassName("ql-editor")[0];
        let imgArr = divQlEditor.getElementsByTagName("img");
        for (let i = 0; i < imgArr.length; i++) {
          imgArr[i].setAttribute("class", "rich-img");
        }
      }
    },
    getContent() {
      return this.editor.container.firstChild.innerHTML;
    }
  }
};
</script>

<style lang="less">
.ql-snow .ql-picker {
  line-height: 24px;
}
.editor {
  position: relative;

  .ql-toolbar {
    padding: 0 10px;
    line-height: 36px;
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;

    .ql-image {
      color: @primary-color;
      line-height: 24px;
      padding: 0 5px;
      width: auto;

      &::after {
        content: attr(value);
        display: inline-block;
      }

      svg {
        margin-top: 3px;
        height: 18px;
      }

      .ql-stroke {
        stroke: @primary-color;
      }

      .ql-fill {
        fill: @primary-color;
      }
    }
  }

  .ql-container {
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
  }

  .ql-editor {
    min-height: 150px;
    max-height: 600px;
    padding: 10px 12px 20px;

    &.ql-blank::before {
      color: rgba(0, 0, 0, 0.3);
      font-family: "PingFang SC", -apple-system, BlinkMacSystemFont, "Segoe UI",
        "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica,
        Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
        "Segoe UI Symbol";
      font-style: normal;
      font-size: 14px;
    }

    img {
      display: block;
      max-width: 100%;
    }
  }

  .calc {
    position: absolute;
    bottom: 4px;
    right: 4px;
    color: rgba(0, 0, 0, 0.3);
    font-size: 12px;
    line-height: 12px;
  }
}
</style>
